﻿using CRM.Models;
using System.Linq;
using CRM.Extensions;
using System.Threading.Tasks;
using System;
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using CRM.Enums;
using CRM.ViewModels.User;
using CRM.Caches;
using CRM.Models.SocialMarketing;
using Z.EntityFramework.Plus;
using static CRM.Extensions.DbSetExtension;

namespace CRM.Services
{
    public class UserService : BaseService
    {
        private readonly UserCache _userCache;

        public static string[] SuperUsers = new[] { "SU", "ADMIN" };

        public UserService(UserCache userCache)
        {
            _userCache = userCache;
        }
        /// <summary>
        /// 初始化公司用户信息
        /// </summary>
        /// <param name="jsonData"></param>
        /// <param name="CurrentUser"></param>
        /// <param name="CurrentCompanyId"></param>
        /// <returns></returns>
        public User InitCompanyUser(CompanySubAdd RequestData, User CurrentUser, int CurrentCompanyId)
        {
            string Pids = CurrentUser.Pids + "," + CurrentUser.Id;

            User UserModel = new()
            {
                UserName = RequestData.UserName,
                TrueName = RequestData.TrueName,
                Password = RequestData.Password,
                Attestation = User.Attestations.DISABLE,
                Email = RequestData.Email,
                RuleId = RequestData.RuleId,
                Type = User.Types.CompanyAdmin,
                Pid = CurrentUser.Id,
                Pids = Pids.Trim(','),
                State = RequestData.State,
                Level = CurrentUser.Level + 1,
                Sort = -Helper.GetNowTimeStamp(),
                HashCode = Helper.GetDeterministicHashCode(RequestData.UserName),
                CompanyId = CurrentCompanyId,
                OemId = RequestData.OemId,
                CreatedAt = DateTime.Now,
                UpdatedAt = DateTime.Now,
                NormalizedEmail = string.Empty,
                EmailConfirmed = false,
            };
            return UserModel;
        }

                /// <summary>
        /// 获取用户详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public User GetInfo(int id)
        {
            return DbContext.Users.Where(m => m.Id == id).FirstOrDefault();
        }

        /// <summary>
        /// 用户被操作日志
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="Remark"></param>
        /// <param name="CurrentUser"></param>
        /// <returns></returns>
        public  Boolean AddUserLog(int UserId, string Remark, User CurrentUser)
        {
            UserLog UserLogModel = new()
            {
                UserId = UserId,
                OperateUserId = CurrentUser.Id,
                OperateUserName = CurrentUser.UserName,
                OperateTrueName = CurrentUser.TrueName,
                OperateIp = HttpContext.GetIPv4(),
                Remark = Remark
            };
             DbContext.UserLog.Add(UserLogModel);
             DbContext.SaveChanges();

            return true;
        }

        /// <summary>
        /// 获取公司管理员可编辑信息
        /// </summary>
        public record EditData(int Id, int RuleId, string UserName, string TrueName, string Email, States State);
        public EditData GetEditCompanyUser(int Id)
        {
            return DbContext.Users.Where(m => m.Id == Id).Select(n => new EditData
            (
                n.Id,
                n.RuleId,
                n.UserName,
                n.TrueName,
                n.Email,
                n.State
            )).FirstOrDefault();
        }

        /// <summary>
        /// 修改公司管理员信息
        /// </summary>
        /// <param name="RequestData"></param>
        /// <param name="UserInfo"></param>
        /// <returns></returns>
        public int EditCompanyUser(CompanySubEdit RequestData,User UserInfo) {

            var dic = new Dictionary<string, object>
            {
                ["UserName"] = RequestData.UserName,
                ["TrueName"] = RequestData.TrueName,
                ["RuleId"] = RequestData.RuleId,
                ["Email"] = RequestData.Email,
                ["State"] = RequestData.State
            };

            return DbContext.Users.Where(m => m.Id == UserInfo.Id).Update(dic);
        }

        /// <summary>
        /// 更新指定公司下用户状态
        /// </summary>
        /// <param name="CompanyId"></param>
        /// <param name="State"></param>
        /// <returns></returns>
        public int EditorUserState(int CompanyId,States State) {
            var dic = new Dictionary<string, object> {
                ["State"] = State
            };
           return DbContext.Users.Where(m=>m.CompanyId == CompanyId).Update(dic);
        }

        /// <summary>
        /// 更新指定用户信息
        /// </summary>
        /// <param name="dic"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public int EditUserById(Dictionary<string, object> dic, int Id)
        {
            return DbContext.Users.Where(m => m.Id == Id).Update(dic);
        }

        /// <summary>
        /// 获取用户日志
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="Request"></param>
        /// <returns></returns>
        public record UserLogData(string OperateTrueName, string Remark, string OperateIp, DateTime CreatedAt);
        public Task<PaginateStruct<UserLogData>> GetUserLogPaginate(int UserId, HttpRequest Request) {
           return DbContext.UserLog.Where(m=>m.UserId == UserId).
                OrderByDescending(i => i.Id).
                Select(n => new UserLogData
            (
                n.OperateTrueName,
                n.Remark,
                n.OperateIp,
                n.CreatedAt
            )).ToPaginateAsync(Request);
        }

        /// <summary>
        /// 获取公司下员工总数
        /// </summary>
        /// <param name="Uid"></param>
        /// <param name="CompanyId"></param>
        /// <param name="OemId"></param>
        /// <returns></returns>
        public int GetUserNum(int Uid,int CompanyId, int OemId) {
            //当前账号开通的用户数量
            var CurrentAccountUserNum = DbContext.Users.
                Where(m => m.Pid == Uid).
                Where(m => m.OemId == OemId).
                Count(m => m.Type == User.Types.Employee || m.Type == User.Types.CompanyAdmin);
            //当前账号开通的公司可开通的用户数量
            var CurrentAccountCompanyUserNum = DbContext.Company.
                Where(m => m.ParentCompanyId == CompanyId).
                Where(m => m.IsOpenUser == Company.IsOpenUsers.DISABLE).
                Sum(m => m.OpenUserNum);
            return CurrentAccountUserNum + CurrentAccountCompanyUserNum;
            //return DbContext.Users.
            //Where(m => m.Pid == Uid).
            //Where(m => m.OemId == OemId).
            //Count(m => m.Type == User.Types.Employee);
            //Count(m => m.Type == User.Types.Employee || m.Type == User.Types.CompanyAdmin);
        }

        /// <summary>
        /// 初始化员工账号
        /// </summary>
        /// <param name="RequestData"></param>
        /// <param name="CurrentUser"></param>
        /// <returns></returns>
        public User InitEmployeeUser(EmployeeSubAdd RequestData, User CurrentUser)
        {
            string Pids = CurrentUser.Pids + "," + CurrentUser.Id;
            User UserModel = new()
            {
                UserName = RequestData.UserName,
                TrueName = RequestData.TrueName,
                Password = RequestData.Password,
                Attestation = User.Attestations.DISABLE,
                Email = RequestData.Email,
                RuleId = RequestData.RuleId,
                GroupId = RequestData.GroupId,
                Type = User.Types.Employee,
                Pid = CurrentUser.Id,
                Pids = Pids.Trim(','),
                State = RequestData.State,
                Level = CurrentUser.Level,
                Sort = -Helper.GetNowTimeStamp(),
                HashCode = Helper.GetDeterministicHashCode(RequestData.UserName),
                CompanyId = CurrentUser.CompanyId,
                OemId = CurrentUser.OemId,
                Validity = RequestData.Validity,
                CreatedAt = DateTime.Now,
                UpdatedAt = DateTime.Now
            }; 
            return UserModel;
        }

        /// <summary>
        /// 获取员工可编辑信息
        /// </summary>
        public record EditEmployeeData(int Id, int RuleId, int GroupId, string UserName, string TrueName, string Email, States State);
        public EditEmployeeData GetEditEmployeeUser(int Id,int CompanyId)
        {
            return DbContext.Users.Where(m => m.Id == Id).
                Where(m=>m.CompanyId == CompanyId).
                Select(n => new EditEmployeeData
            (
                n.Id,
                n.RuleId,
                n.GroupId,
                n.UserName,
                n.TrueName,
                n.Email,
                n.State
            )).FirstOrDefault();
        }

        /// <summary>
        /// 更新员工用户信息
        /// </summary>
        /// <param name="RequestData"></param>
        /// <param name="UserInfo"></param>
        /// <returns></returns>
        public int EditEmployeeUser(EmployeeSubEdit RequestData, User UserInfo)
        {

            var dic = new Dictionary<string, object>
            {
                ["UserName"] = RequestData.UserName,
                ["TrueName"] = RequestData.TrueName,
                ["RuleId"] = RequestData.RuleId,
                ["GroupId"] = RequestData.GroupId,
                ["Email"] = RequestData.Email,
                ["State"] = RequestData.State,
                ["Validity"] = RequestData.Validity,
            };

            return DbContext.Users.Where(m => m.Id == UserInfo.Id).Update(dic);
        }

        /// <summary>
        /// 绑定社交帐号
        /// </summary>
        /// <param name="socialAccount"></param>
        public async Task BindSocialAccount(SocialAccount socialAccount)
        {
            DbContext.Attach(CurrentUser);
            CurrentUser.SocialAccount = socialAccount;
            await DbContext.SaveChangesAsync();
            _userCache.FlushItem(UserManager, HttpContext.User);
        }

     
    }
}
